/**
 * @file CCircle.cpp
 * @author redfrogotr
 * @brief 利用平面点类CPoint设计组合类圆类CCircle
 * @date 2022-04-03
 */

#include <iostream>
#include <cmath>    // sqrt, pow

using namespace std;

class CPoint
{
private:
    double x, y;    // the x and y coordinates of point

public:
    CPoint(double x = 0, double y = 0) : x(x), y(y) {}
    void setX(double x) { this->x = x; }
    double getX() { return x; }
    void setY(double y) { this->y = y; }
    double getY() { return y; }
    double operator-(const CPoint& point) {
        return sqrt(pow(x - point.x, 2) + pow(y - point.y, 2));
    }
    void move(double dx, double dy) {
        x += dx, y += dy;
    }
};
ostream& operator<<(ostream& out, CPoint& point) {
    out << "(" << point.getX() << "," << point.getY() << ")";
    return out;        
}

class CCircle
{
private:
    CPoint center;
    double radium;
    static double Pi;

public:
    CCircle(double x = 0, double y = 0, double radium = 1) : center(x, y), radium(radium) {}
    CCircle(CPoint p, double radium = 1) : center(p), radium(radium) {}
    CPoint& getCenter() { return center; }
    double getRadium() { return radium; }
    double getLength() { return 2 * Pi * radium; }
    int judge(CCircle& circle) {
        double centerDistance = abs(center - circle.center);
        double radiumSum = radium + circle.radium;
        if (abs(centerDistance - radiumSum) < 10e-6) return 0;
        if (centerDistance < radiumSum) return 1;
        return -1;
    }
    void move(double dx, double dy) { center.move(dx, dy); }
    static void setPi(double pi) { Pi = pi; }
};
double CCircle::Pi = 3.14;

ostream& operator<<(ostream& out, CCircle& circle) {
    out << "center: " << circle.getCenter() << ", "
        << "radium: " << circle.getRadium();
    return out;
}

int main(int argc, char const *argv[])
{
    CPoint p1(2, 3), p2;
    cout << p1 << " " << p2 << endl;
    cout << p1 - p2 << endl;

    CCircle c1(p1, 2), c2(p2, 3), c3(0, 4);
    CCircle::setPi(3.14);
    cout << c1 << endl 
        << "length: " << c1.getLength() << endl;
    cout << c1.judge(c2) << " " << c2.judge(c3) << endl;

    c1.move(1, 1);
    cout << c1 << endl;

    return 0;
}
